8. Consultas de Referencias
Cruzadas
Una consulta de referencias cruzadas es aquella que nos
permite visualizar los datos en filas y
en columnas, estilo tabla, por ejemplo:
Producto / Año | 1996 | 1997 |
Pantalones | 1.250 | 3.000 |
Camisas | 8.560 | 1.253 |
Zapatos | 4.369 | 2.563 |
Si tenemos una tabla de productos y
otra tabla de pedidos, podemos visualizar en total de productos
pedidos por año para un artículo determinado, tal y
como se visualiza en la tabla anterior.
La sintaxis para este tipo de consulta es la siguiente:
TRANSFORM función
agregada instrucción select PIVOT campo pivot
[IN (valor1[, valor2[, …]])]
En donde:
función
agregada
Es una función SQL agregada
que opera sobre los datos
seleccionados.
instrucción select
Es una instrucción SELECT.
campo pivot
Es el campo o expresión que desea utilizar para crear las
cabeceras de la columna en el resultado de la consulta.
valor1, valor2
Son valores fijos
utilizados para crear las cabeceras de la columna.
Para resumir datos utilizando una consulta de referencia cruzada,
se seleccionan los valores de
los campos o expresiones especificadas como cabeceras de columnas
de tal forma que pueden verse los datos en un formato más
compacto que con una consulta de selección.
TRANSFORM es opcional pero si se incluye es la primera
instrucción de una cadena SQL. Precede a
la instrucción SELECT que especifica los campos utilizados
como encabezados de fila y una cláusula GROUP BY que
especifica el agrupamiento de las filas. Opcionalmente puede
incluir otras cláusulas como por ejemplo WHERE, que
especifica una selección
adicional o un criterio de ordenación .
Los valores
devueltos en campo pivot se utilizan como encabezados de columna
en el resultado de la consulta. Por ejemplo, al utilizar las
cifras de ventas en el
mes de la venta como pivot
en una consulta de referencia cruzada se crearían 12
columnas. Puede restringir el campo pivot para crear encabezados
a partir de los valores fijos
(valor1, valor2) listados en la cláusula opcional IN.
También puede incluir valores fijos, para los que no
existen datos, para crear columnas adicionales.
Ejemplos
TRANSFORM Sum(Cantidad) AS Ventas SELECT
Producto,
Cantidad FROM
Pedidos WHERE Fecha Between #01-01-98# And #12-31-98# GROUP
BY Producto
ORDER BY Producto PIVOT DatePart("m", Fecha);
Crea una consulta de tabla de referencias cruzadas que muestra las
ventas de productos por mes para un año específico.
Los meses aparecen de izquierda a derecha como columnas y los
nombres de los productos aparecen de arriba hacia abajo como
filas.
TRANSFORM Sum(Cantidad) AS Ventas SELECT Compania FROM
Pedidos
WHERE Fecha Between #01-01-98# And #12-31-98# GROUP BY
Compania
ORDER BY Compania PIVOT "Trimestre " & DatePart("q", Fecha)
In ('Trimestre1',
Trimestre2', 'Trimestre 3', 'Trimestre 4');
Crea una consulta de tabla de referencias cruzadas que muestra las
ventas de productos por trimestre de cada proveedor en el
año indicado. Los trimestres aparecen de izquierda a
derecha como columnas y los nombres de los proveedores
aparecen de arriba hacia abajo como filas.
Un caso práctico:
Se trata de resolver el siguiente problema: tenemos una tabla de
productos con dos campos, el código
y el nombre del producto, tenemos otra tabla de pedidos en la que
anotamos el código
del producto, la fecha del pedido y la cantidad pedida. Deseamos
consultar los totales de producto por año, calculando la
media anual de ventas.
Estructura y datos de las tablas:
1. Artículos:
ID | Nombre |
1 | Zapatos |
2 | Pantalones |
3 | Blusas |
2. Pedidos:
Id | Fecha | Cantidad |
1 | 11/11/1996 | 250 |
2 | 11/11/1996 | 125 |
3 | 11/11/1996 | 520 |
1 | 12/10/1996 | 50 |
2 | 04/05/1996 | 250 |
3 | 05/08/1996 | 100 |
1 | 01/01/1997 | 40 |
2 | 02/08/1997 | 60 |
3 | 05/10/1997 | 70 |
1 | 12/12/1997 | 8 |
2 | 15/12/1997 | 520 |
3 | 17/10/1997 | 1250 |
Para resolver la consulta planteamos la siguiente
consulta:
TRANSFORM Sum(Pedidos.Cantidad) AS Resultado SELECT Nombre AS
Producto,
Pedidos.Id AS Código, Sum(Pedidos.Cantidad) AS TOTAL,
Avg(Pedidos.Cantidad)
AS Media FROM Pedidos INNER JOIN Artículos ON Pedidos.Id =
Artículos.Id
GROUP BY Pedidos.Id, Artículos.Nombre PIVOT
Year(Fecha); y obtenemos el siguiente resultado:
Producto | Código | TOTAL | Media | 1996 | 1997 |
Zapatatos | 1 | 348 | 87 | 300 | 48 |
Pantalones | 2 | 955 | 238,75 | 375 | 580 |
Blusas | 3 | 1940 | 485 | 620 | 1320 |
Comentarios a la consulta:
La clásula TRANSFORM indica el valor que
deseamos visualizar en las columnas que realmente pertenecen a la
consulta, en este caso 1996 y 1997, puesto que las demás
columnas son opcionales.
SELECT especifica el nombre de las columnas opcionales que
deseamos visualizar, en este caso Producto, Código, Total
y Media, indicando el nombre del campo que deseamos mostrar en
cada columna o el valor de la
misma. Si incluimos una función de cálculo el
resultado se hará en base a los datos de la fila actual y
no al total de los datos.
FROM especifica el origen de los datos. La primera tabla que debe
figurar es aquella de donde deseamos extraer los datos, esta
tabla debe contener al menos tres campos, uno para los
títulos de la fila, otros para los títulos de la
columna y otro para calcular el valor de las celdas.
En este caso en concreto se
deseaba visualizar el nombre del producto, como el tabla de
pedidos sólo figuraba el código del mismo se
añadió una nueva columna en la cláusula
select llamada Producto que se corresponda con el campo Nombre de
la tabla de artículos. Para vincular el código del
artículo de la tabla de pedidos con el nombre del misma de
la tabla artículos se insertó la cláusula
INNER JOIN.
La cláusula GROUP BY especifica el agrupamiento de los
registros,
contrariamente a los manuales de
instrucción esta cláusula no es opcional ya que
debe figurar siempre y debemos agrupar los registros por el
campo del cual extraemos la información. En este caso existen dos
campos del cual extraemos la información: pedidos.cantidad y
artículos.nombre, por ellos agrupamos por los campos.
Para finalizar la cláusula PIVOT indica el nombre de las
columnas no opcionales, en este caso 1996 y 1997 y como vamos a
el dato que aparecerá en las columnas, en este caso
empleamos el año en que se produjo el pedido,
extrayéndolo del campo pedidos.fecha.
Otras posibilidades de fecha de la cláusula pivot son las
siguientes:
1. Para agrupamiento por Trimestres
PIVOT "Tri " & DatePart("q",[Fecha]);
2. Para agrupamiento por meses (sin tener en cuenta el
año)
PIVOT Format([Fecha],"mmm") In ("Ene", "Feb", "Mar", "Abr",
"May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic");
3. Para agrupar por días
PIVOT Format([Fecha],"Short Date");
9. Consultas de
Unión Internas
Las vinculaciones entre tablas se realiza mediante la
cláusula INNER que combina registros de dos tablas siempre
que haya concordancia de valores en un campo común. Su
sintaxis es:
SELECT campos FROM tb1 INNER JOIN tb2 ON tb1.campo1 comp
tb2.campo2
En donde:
tb1, tb2
Son los nombres de las tablas desde las que se combinan los
registros.
campo1, campo2
Son los nombres de los campos que se combinan. Si no son
numéricos, los campos deben ser del mismo tipo de datos y
contener el mismo tipo de datos, pero no tienen que tener el
mismo nombre.
comp
Es cualquier operador de comparación relacional : =, <,
>, <=, >=, o <>.
Se puede utilizar una operación INNER JOIN en cualquier
cláusula FROM. Esto crea una combinación por
equivalencia, conocida también como unión interna.
Las combinaciones Equi son las más comunes; éstas
combinan los registros de dos tablas siempre que haya
concordancia de valores en un campo común a ambas tablas.
Se puede utilizar INNER JOIN con las tablas Departamentos y
Empleados para seleccionar todos los empleados de cada
departamento. Por el contrario, para seleccionar todos los
departamentos (incluso si alguno de ellos no tiene ningún
empleado asignado) se emplea LEFT JOIN o todos los empleados
(incluso si alguno no está asignado a ningún
departamento), en este caso RIGHT JOIN.
Si se intenta combinar campos que contengan datos Memo u Objeto
OLE, se produce un error. Se pueden combinar dos campos
numéricos cualesquiera, incluso si son de diferente tipo
de datos. Por ejemplo, puede combinar un campo Numérico
para el que la propiedad Size
de su objeto Field está establecida como Entero, y un
campo Contador.
El ejemplo siguiente muestra cómo podría combinar
las tablas Categorías y Productos basándose en el
campo IDCategoria:
SELECT Nombre_Categoría, NombreProducto
FROM Categorias INNER JOIN Productos
ON Categorias.IDCategoria = Productos.IDCategoria;
En el ejemplo anterior, IDCategoria es el campo
combinado, pero no está incluido en la salida de la
consulta ya que no está incluido en la instrucción
SELECT. Para incluir el campo combinado, incluir el nombre del
campo en la instrucción SELECT, en este caso,
Categorias.IDCategoria.
También se pueden enlazar varias cláusulas ON en
una instrucción JOIN, utilizando la sintaxis
siguiente:
SELECT campos
FROM tabla1 INNER JOIN tabla2
ON tb1.campo1 comp tb2.campo1 AND
ON tb1.campo2 comp tb2.campo2) OR
ON tb1.campo3 comp tb2.campo3)];
También puede anidar instrucciones JOIN
utilizando la siguiente sintaxis:
SELECT campos
FROM tb1 INNER JOIN
(tb2 INNER JOIN [( ]tb3
[INNER JOIN [( ]tablax [INNER JOIN …)]
ON tb3.campo3 comp tbx.campox)]
ON tb2.campo2 comp tb3.campo3)
ON tb1.campo1 comp tb2.campo2;
Un LEFT JOIN o un RIGHT JOIN puede anidarse dentro de un
INNER JOIN, pero un INNER JOIN no puede anidarse dentro de un
LEFT JOIN o un RIGHT JOIN.
Ejemplo
SELECT DISTINCTROW Sum([Precio unidad]
* [Cantidad]) AS [Ventas],
[Nombre] & " " & [Apellidos] AS [Nombre completo] FROM
[Detalles de pedidos],
Pedidos, Empleados, Pedidos INNER JOIN [Detalles de pedidos] ON
Pedidos.
[ID de pedido] = [Detalles de pedidos].[ID de pedido], Empleados
INNER JOIN
Pedidos ON Empleados.[ID de empleado] = Pedidos.[ID de empleado]
GROUP BY
[Nombre] & " " & [Apellidos];
Crea dos combinaciones equivalentes: una entre las tablas
Detalles de pedidos y Pedidos, y la otra entre las tablas Pedidos
y Empleados. Esto es necesario ya que la tabla Empleados no
contiene datos de ventas y la tabla Detalles de pedidos no
contiene datos de los empleados. La consulta produce una lista de
empleados y sus ventas totales.
Si empleamos la cláusula INNER en la consulta se
seleccionarán sólo aquellos registros de la tabla
de la que hayamos escrito a la izquierda de INNER JOIN que
contengan al menos un registro de la
tabla que hayamos escrito a la derecha. Para solucionar esto
tenemos dos cláusulas que sustituyen a la palabra clave
INNER, estas cláusulas son LEFT y RIGHT. LEFT toma todos
los registros de la tabla de la izquierda aunque no tengan
ningún registro en la
tabla de la izquierda. RIGHT realiza la misma operación
pero al contrario, toma todos los registros de la tabla de la
derecha aunque no tenga ningún registro en la tabla de la
izquierda.
10. Consultas de
Unión Externas
Se utiliza la operación UNION para crear una
consulta de unión, combinando los resultados de dos o
más consultas o tablas independientes. Su sintaxis es:
[TABLE] consulta1 UNION [ALL] [TABLE]
consulta2 [UNION [ALL] [TABLE] consultan [ … ]]
En donde:
consulta1, consulta2, consultan
Son instrucciones SELECT, el nombre de una consulta almacenada o
el nombre de una tabla almacenada precedido por la palabra clave
TABLE.
Puede combinar los resultados de dos o más consultas,
tablas e instrucciones SELECT, en cualquier orden, en una
única operación UNION. El ejemplo siguiente combina
una tabla existente llamada Nuevas Cuentas y una
instrucción SELECT:
TABLE [Nuevas Cuentas] UNION
ALL SELECT * FROM Clientes
WHERE [Cantidad pedidos] > 1000;
Si no se indica lo contrario, no se devuelven registros
duplicados cuando se utiliza la operación UNION, no
obstante puede incluir el predicado ALL para asegurar que se
devuelven todos los registros. Esto hace que la consulta se
ejecute más rápidamente. Todas las consultas en una
operación UNION deben pedir el mismo número de
campos, no obstante los campos no tienen porqué tener el
mismo tamaño o el mismo tipo de datos.
Se puede utilizar una cláusula GROUP BY y/o HAVING en cada
argumento consulta para agrupar los datos devueltos. Puede
utilizar una cláusula ORDER BY al final del último
argumento consulta para visualizar los datos devueltos en un
orden específico.
SELECT [Nombre de compañía], Ciudad FROM Proveedores
WHERE
País = 'Brasil' UNION
SELECT [Nombre de compañía], Ciudad FROM Clientes
WHERE País = "Brasil"
Recupera los nombres y las ciudades de todos proveedores y
clientes de Brasil
SELECT [Nombre de compañía], Ciudad FROM
Proveedores WHERE País = 'Brasil'
UNION SELECT [Nombre de compañía], Ciudad FROM
Clientes WHERE País =
'Brasil' ORDER BY Ciudad
Recupera los nombres y las ciudades de todos proveedores y
clientes radicados en Brasil, ordenados por el nombre de la
ciudad
SELECT [Nombre de compañía], Ciudad FROM
Proveedores WHERE País = 'Brasil'
UNION SELECT [Nombre de compañía], Ciudad FROM
Clientes WHERE País =
'Brasil' UNION SELECT [Apellidos], Ciudad FROM Empleados WHERE
Región =
'América
del Sur'
Recupera los nombres y las ciudades de todos los proveedores y
clientes de brasil y los apellidos y las ciudades de todos los
empleados de América
del Sur
TABLE [Lista de clientes] UNION TABLE [Lista de proveedores]
Recupera los nombres y códigos de todos los proveedores y
clientes
11. Estructuras de
las Tablas
Creación de Tablas Nuevas
Si se está utilizando el motor de datos de
Microsoft para
acceder a bases de datos
access,
sólo se puede emplear esta instrucción para crear
bases de datos
propias de access. Su
sintaxis es:
CREATE TABLE tabla (campo1 tipo (tamaño) índice1
,
campo2 tipo (tamaño) índice2 , …,
índice multicampo , … )
En donde:
Parte | Descripción |
tabla | Es el nombre de la tabla que se va a |
campo1 | Es el nombre del campo o de los campos que se van |
tipo | Es el tipo de datos de campo en la nueva tabla. |
tamaño | Es el tamaño del campo sólo se |
índice1 | Es una cláusula CONSTRAINT |
índice multicampos | Es una cláusula CONSTRAINT |
CREATE TABLE Empleados (Nombre TEXT (25) , Apellidos
TEXT (50));
Crea una nueva tabla llamada Empleados con dos campos, uno
llamado Nombre de tipo texto y
longutid 25 y otro llamado apellidos con longitud 50.
CREATE TABLE Empleados (Nombre TEXT (10), Apellidos TEXT,
Fecha_Nacimiento DATETIME) CONSTRAINT IndiceGeneral UNIQUE
([Nombre], [Apellidos], [Fecha_Nacimiento]);
Crea una nueva tabla llamada Empleados con un campo Nombre de
tipo texto y longitud 10, otro con llamado Apellidos de tipo
texto y longitud predeterminada (50) y uno más llamado
Fecha_Nacimiento de tipo Fecha/Hora. También crea un
índice único (no permite valores repetidos) formado
por los tres campos.
CREATE TABLE Empleados (ID INTEGER CONSTRAINT IndicePrimario
PRIMARY,
Nombre TEXT, Apellidos TEXT, Fecha_Nacimiento DATETIME);
Crea una tabla llamada Empleados con un campo Texto de longitud
predeterminada (50) llamado Nombre y otro igual llamado
Apellidos, crea otro campo llamado Fecha_Nacimiento de tipo
Fecha/Hora y el campo ID de tipo entero el que establece como
clave principal.
11.2 La cláusula CONSTRAINT
Se utiliza la cláusula CONSTRAINT en las instrucciones
ALTER TABLE y CREATE TABLE para crear o eliminar índices.
Existen dos sintaxis para esta cláusula dependiendo si
desea Crear ó Eliminar un índice de un único
campo o si se trata de un campo multiíndice. Si se utiliza
el motor de datos de
Microsoft,
sólo podrá utilizar esta cláusula con las
bases de datos propias de dicho motor.
Para los índices de campos únicos:
CONSTRAINT nombre {PRIMARY KEY | UNIQUE | REFERENCES tabla
externa
[(campo externo1, campo externo2)]}
Para los índices de campos múltiples:
CONSTRAINT nombre {PRIMARY KEY (primario1[, primario2 [, …]])
|
UNIQUE (único1[, único2 [, …]]) |
FOREIGN KEY (ref1[, ref2 [, …]]) REFERENCES tabla externa
[(campo externo1
[,campo externo2 [, …]])]}
Parte | Descripción |
nombre | Es el nombre del índice que se va a |
primarioN | Es el nombre del campo o de los campos que forman |
únicoN | Es el nombre del campo o de los campos que forman |
refN | Es el nombre del campo o de los campos que forman |
tabla externa | Es el nombre de la tabla que contiene el campo o |
campos externos | Es el nombre del campo o de los campos de la tabla |
Si se desea crear un índice para un campo cuando
se esta utilizando las instrucciones ALTER TABLE o CREATE TABLE
la cláusula CONTRAINT debe aparecer inmediatamente
después de la especificación del campo
indexeado.
Si se desea crear un índice con múltiples campos
cuando se está utilizando las instrucciones ALTER TABLE o
CREATE TABLE la cláusula CONSTRAINT debe aparecer fuera de
la cláusula de creación de tabla.
Tipo de Indice | Descripción |
UNIQUE | Genera un índece de clave única. Lo |
PRIMARY KEY | Genera un índice primario el campo o los |
FOREIGN KEY | Genera un índice externo (toma como valor |
Creación de Índices
Si se utiliza el motor de datos Jet de Microsoft sólo se
pueden crear índices en bases de datos del mismo motor. La
sintaxis para crear un índice en ua tabla ya definida en
la siguiente:
CREATE [ UNIQUE ] INDEX índice
ON tabla (campo [ASC|DESC][, campo [ASC|DESC], …])
[WITH { PRIMARY | DISALLOW NULL | IGNORE NULL }]
En donde:
Parte | Descripción |
índice | Es el nombre del índice a crear. |
tabla | Es el nombre de una tabla existentes en la que se |
campo | Es el nombre del campo o lista de campos que |
ASC|DESC | Indica el orden de los valores de lso campos ASC |
UNIQUE | Indica que el indice no puede contener valores |
DISALLOW NULL | Prohibe valores nulos en el |
IGNORE NULL | Excluye del índice los valores nulos |
PRIMARY | Asigna al índice la categoría de |
Se puede utilizar CREATE INDEX para crear un pseudo
índice sobre una tabla adjunta en una fuente de datos ODBC
tal como SQL Server que
no tenga todavía un índice. No necesita permiso o
tener acceso a un servidor remoto
para crear un pseudo índice, además la base de datos
remota no es consciente y no es afectada por el pseudo
índice. Se utiliza la misma sintaxis para las tabla
adjunta que para las originales. Esto es especialmente
útil para crear un índice en una tabla que
sería de sólo lectura debido
a la falta de un índice.
CREATE INDEX MiIndice ON Empleados (Prefijo, Telefono);
Crea un índice llamado MiIndice en la tabla empleados con
los campos Prefijo y Telefono.
CREATE UNIQUE INDEX MiIndice ON Empleados (ID) WITH DISALLOW
NULL;
Crea un índice en la tabla Empleados utilizando el campo
ID, obligando que que el campo ID no contenga valores nulos ni
repetidos.
Modificar el Diseño
de una Tabla
Modifica el diseño
de una tabla ya existente, se puden modificar los campos o los
índices existentes. Su sintaxis es:
ALTER TABLE tabla {ADD {COLUMN tipo de campo[(tamaño)]
[CONSTRAINT índice]
CONSTRAINT índice multicampo} |
DROP {COLUMN campo I CONSTRAINT nombre del índice} }
En donde:
Parte | Descripción |
tabla | Es el nombre de la tabla que se desea |
campo | Es el nombre del campo que se va a añadir o |
tipo | Es el tipo de |
tamaño | El el tamaño del campo que se va a |
índice | Es el nombre del índice del campo (cuando |
índice multicampo | Es el nombre del índice del campo |
Operación | Descripción |
ADD COLUMN | Se utiliza para añadir un nuevo campo a la |
ADD | Se utliza para agregar un índice de |
DROP COLUMN | Se utliza para borrar un campo. Se especifica |
DROP | Se utiliza para eliminar un índice. Se |
ALTER TABLE Empleados ADD COLUMN Salario
CURRENCY;
Agrega un campo Salario de tipo
Moneda a la tabla Empleados.
ALTER TABLE Empleados DROP COLUMN Salario;
Elimina el campo Salario de la tabla Empleados.
ALTER TABLE Pedidos ADD CONSTRAINT RelacionPedidos FOREIGN
KEY
(ID_Empleado) REFERENCES Empleados (ID_Empleado);
Agrega un indice externo a la tabla Pedidos. El índice
externo se basa en el campo ID_Empleado y se refiere al campo
ID_Empleado de la tabla Empleados. En este ejemplo no es
necesario indicar el campo junto al nombre de la tabla en la
cláusula REFERENCES, pues ID_Empleado es la clave
principal de la tabla Empleados.
ALTER TABLE Pedidos DROP CONSTRAINT RelacionPedidos;
Elimina el índide de la tabla Pedidos.
Las consultas con parámetros son aquellas cuyas
condiciones de búsqueda se definen mediante
parámetros. Si se ejecutan directamente desde la base de datos
donde han sido definidas aparecerá un mensaje solicitando
el valor de cada uno de los parámetros. Si deseamos
ejecutarlas desde una aplicación hay que asignar primero
el valor de los parámetros y después ejecutarlas.
Su sintaxis es la siguiente:
PARAMETERS nombre1 tipo1, nombre2 tipo2, … , nombreN tipoN
Consulta
En donde:
Parte | Descripción |
nombre | Es el nombre del parámetro |
tipo | Es el tipo de |
consulta | Una consulta SQL |
Puede utilizar nombre pero no tipo de datos en una
cláusula WHERE o HAVING.
PARAMETERS Precio_Minimo Currency, Fecha_Inicio DateTime;
SELECT IDPedido, Cantidad FROM Pedidos WHERE Precio >
Precio_Minimo
AND FechaPedido >= Fecha_Inicio;
El ejemplo siguiente muestra como utilizar los parámetros
en el programa de
Visual Basic:
Public Sub GeneraConsulta()
Dim SQL As String
Dim Qd As QueryDef
Dim Rs As Recordset
SQL = "PARAMETERS Precio_Minimo Currency, Fecha_Inicio
DateTime; "
SQL = SQL & "SELECT IDPedido, Cantidad FROM Pedidos WHERE
Precio > "
SQL = SQL & "Precio_Minimo AND FechaPedido >=
Fecha_Inicio; "
Set Qd = BaseDatos.CreateQueryDef(MiConsulta, SQL)
Qd.Parameters!Precio_Minimo = 2
Qd.Parameters!FechaInicio = #31/12/95#
Set Rs = Qd.OpenRecordset()
End Sub
Ejemplo:
PARAMETERS [Escriba los Apellidos:] Text; SELECT * FROM
Empleados
WHERE [Escriba los Apellidos:] = [Apellidos];
La ejecución desde la base de datos solicita al usuario
los apellidos del empleado y después muestra los
resultados.
Para el acceso a bases de datos externas se utiliza la
cláusula IN. Se puede acceder a base de datos dBase,
Paradox o Btrieve. Esta cláusula sólo permite la
conexión de una base de datos externa a la vez. Una base
de datos externa es una base de datos que no sea la activa.
Aunque para mejorar los rendimientos es mejor adjuntarlas a la
base de datos actual y trabajar con ellas.
Para especificar una base de datos que no pertenece a Access Basic, se
agrega un punto y coma (;) al nombre y se encierra entre comillas
simples. También puede utilizar la palabra reservada
DATABASE para especificar la base de datos externa. Por ejemplo,
las líneas siguientes especifican la misma tabla:
FROM Tabla IN '[dBASE IV;
DATABASE=C:DBASEDATOSVENTAS;]';
FROM Tabla IN 'C:DBASEDATOSVENTAS' 'dBASE IV;'
Acceso a una base de datos externa de Microsoft
Access:
SELECT IDCliente FROM Clientes IN MISDATOS.MDB WHERE IDCliente
Like 'A*';
En donde MISDATOS.MDB es el nombre de una base de datos de
Microsoft Access
que contiene la tabla Clientes.
Acceso a una base de datos externa de dBASE III o IV:
SELECT IDCliente FROM Clientes IN 'C:DBASEDATOSVENTAS' 'dBASE
IV';
WHERE IDCliente Like 'A*';
Para recuperar datos de una tabla de dBASE III+ hay que utilizar
'dBASE III+;' en lugar de 'dBASE IV;'.
Acceso a una base de datos de Paradox 3.x o 4.x:
SELECT IDCliente FROM Clientes IN 'C:PARADOXDATOSVENTAS'
'Paradox 4.x;' WHERE IDCliente Like 'A*';
Para recuperar datos de una tabla de Paradox versión 3.x,
hay que sustituir 'Paradox 4.x;' por 'Paradox 3.x;'.
Acceso a una base de datos de Btrieve:
SELECT IDCliente FROM Clientes IN
'C:BTRIEVEDATOSVENTASFILE.DDF'
'Btrieve;' WHERE IDCliente Like 'A*';
C:BTRIEVEDATOSVENTASFILE.DDF es la ruta de acceso y nombre de
archivo del
archivo de
definición de datos de Btrieve.
14. Omitir los
Permisos de Ejecución
En entornos de bases de datos con permisos de seguridad para
grupos de
trabajo se puede utilizar la cláusula WITH OWNERACCESS
OPTION para que el usuario actual adquiera los derechos de propietario a la
hora de ejecutar la consulta. Su sintaxis es:
instrucción sql WITH OWNERACCESS OPTION
SELECT Apellido, Nombre, Salario FROM Empleados ORDER BY
Apellido
WITH OWNERACCESS OPTION;
Esta opción requiere que esté declarado el acceso
al fichero de grupo de
trabajo (generalmente system.mda ó system .mdw) de la base
de datos actual.
15. La Cláusula PROCEDURE
Esta cláusula es poco usual y se utiliza para
crear una consulta a la misma vez que se ejecuta, opcionalmente
define los parámetros de la misma. Su sintaxis es la
siguiente:
PROCEDURE NombreConsulta Parámetro1 tipo1, …. ,
ParámetroN tipon ConsultaSQL
En donde:
Parte | Descripción |
NombreConsulta | Es el nombre con se guardará la consulta en |
Parámetro | Es el nombre de parámetro o de los |
tipo | Es el tipo de |
ConsultaSQL | Es la consulta que se desea grabar y |
PROCEDURE Lista_Categorias; SELECT DISTINCTROW
Nombre_Categoria,
ID_Categoría FROM Categorias ORDER BY
Nombre_Categoria;
Asigna el nombre Lista_de_categorías a la consulta y la
ejecuta.
PROCEDURE Resumen Fecha_Inicio DateTime, Fecha_Final DateTime;
SELECT
DISTINCTROW Fecha_Envio, ID_Pedido, Importe_Pedido,
Format(Fecha_Envio, "yyyy")
AS Año FROM Pedidos WHERE Fecha_Envio Between Fecha_Inicio
And Fecha_Final;
Asigna el nombre Resumen a la consulta e incluye dos
parámetros.
Resolución de Problemas
Buscar Información duplicada en un campo de una tabla.
Para generar este tipo de consultas lo más sencillo es
utilizar el asistente de consultas de Access, editar la
sentencia SQL de la consulta y pegarla en nuestro código.
No obstante este tipo de consulta se consigue de la siguiente
forma:
SELECT DISTINCTROW Lista de Campos a Visualizar FROM Tabla
WHERE CampoDeBusqueda In (SELECT CampoDeBusqueda FROM Tabla As
psudónimo
GROUP BY CampoDeBusqueda HAVING Count(*)>1 ) ORDER BY
CampoDeBusqueda;
Un caso práctico, si deseamos localizar aquellos empleados
con igual nombre y visualizar su código correspondiente,
la consulta sería la siguiente:
SELECT DISTINCTROW Empleados.Nombre, Empleados.IdEmpleado
FROM Empleados WHERE Empleados.Nombre In (SELECT Nombre FROM
Empleados As Tmp GROUP BY Nombre HAVING Count(*)>1)
ORDER BY Empleados.Nombre;
Recuperar Registros de una tabla que no contengan registros
relacionados en otra.
Este tipo de consulta se emplea en situaciones tales como saber
que productos no se han vendido en un determinado periodo de
tiempo,
SELECT DISTINCTROW Productos.IdProducto, Productos.Nombre FROM
Productos
LEFT JOIN Pedidos ON Productos.IdProducto = Pedidos.IdProduct
WHERE
(Pedidos.IdProducto Is Null) AND (Pedidos.Fecha Between
#01-01-98# And #01-30-98#);
La sintaxis es sencilla, se trata de realizar una unión
interna entre dos tablas seleccionadas mediante un LEFT JOIN,
establecimiendo como condición que el campo relacionado de
la segunda sea Null.
Utlizar SQL desde Visual Basic
Existen dos tipos de consultas SQL: las consultas de
selección (nos devuelven datos) y las consultas de
acción (aquellas que no devuelven ningún registro).
Ambas pueden ser tratadas en Visual Basic pero
de forma diferente.
Las consultas de selección se ejecutan recogiendo la
información en un recordset previamente definido mediante
la instrucción openrecordset(), por ejemplo:
Dim SQL as String
Dim RS as recordset
SQL = "SELECT * FROM Empleados;"
Set RS=MiBaseDatos.OpenRecordSet(SQL)
Si la consula de selección se encuentra almacenada en una
consulta de la base de datos:
Set RS=MiBaseDatos.OpenRecordset("MiConsulta")
Las consultas de acción, al no devolver ningún
registro, no las podemos asignar a ningún recordset, en
este caso la forma de ejecutarlas es mediante los métodos
Execute y ExecuteSQL (para bases de datos ODBC), por ejemplo:
Dim SQL as string
SQL = "DELETE * FROM Empleados WHERE Categoria =
'Ordenanza';"
MiBaseDatos.Execute SQL
Funciones de
Visual Basic
utilizables en una Instrucción SQL
Función | Sintaxis | Descripción |
Now | Variable= Now | Devuelve la fecha y la hora actual del |
Date | Variable=Date | Devuelve la fecha actual del sistema |
Time | Variable=Time | Devuelve la hora actual del sistema |
Year | Variable=Year(Fecha) | Devuelve los cuatro dígitos |
Month | Variable=Month(Fecha) | Devuelve el número del mes del |
Day | Variable=Day(Fecha) | Devuelve el número del día del mes |
Weekday | Variable=Weekday(Fecha) | Devuelve un número entero que representa el |
Hour | Variable=Hour(Hora) | Devuelve un número entre 0 y 23 que |
Minute | Variable=Minute(Hora) | Devuelve un número entre 0 y 59 que |
Second | Variable=Second(Hora) | Devuelve un número entre 0 y 59 que |
DatePart
Esta función devuelve una parte señalada de una
fecha concreta. Su sintaxis es:
DatePart(Parte, Fecha, ComienzoSemana, ComienzoAño)
Parte representa a la porción de fecha que se desea
obtener, los posibles valores son:
Valor | Descripción |
yyyy | Año |
q | Trimestre |
m | Mes |
y | Día del año |
d | Día del mes |
w | Día de la semana |
ww | Semana del año |
h | Hora |
m | Minutos |
s | Segundos |
ComienzoSemana indica el primer día de la semana.
Los posibles valores son:
Valor | Descripción |
0 | Utiliza el valor pode efecto del |
1 | Domingo (Valor predeterminado) |
2 | Lunes |
3 | Martes |
4 | Miércoles |
5 | Jueves |
6 | Viernes |
7 | Sábado |
ComienzoAño indica cual es la primera semana del
año; los posibles valores son:
Valor | Descripción |
0 | Valor del sistema |
1 | Comienza el año el 1 de enero (valor |
2 | Empieza con la semana que tenga al memos cuatro |
3 | Empieza con la semana que esté contenida |
Evaluar valores antes de ejecutar la Consuta.
Dentro de una sentencia SQL podemos emplear la función iif
para indicar las condiciones de búsqueda. La sintaxis de
la función iif es la siguiente:
iif(Expresion,Valor1,Valor2)
En donde Expresión es la sentencia que evaluamos; si
Expresión es verdadera entonces se devuelve Valor1, si
Expresión es falsa se devuelve Valor2.
SELECT * Total FROM Empleados WHERE Apellido =
iff(TX_Apellido.Text <> '', TX_Apellido.Text, *) ;
Supongamos que en un formulario tenemos una casilla de texto
llamanda TX_Apellido. Si cuando ejecutamos esta consulta la
casilla contiene algún valor se devuelven todos los
empleados cuyo apellido coincida con el texto de la casilla, en
caso contrario se devuelven todos los empleados.
SELECT Fecha, Producto, Cantidad, (iif(CodigoPostal>=28000
And
CodigoPostal <=28999,'Madrid','Nacional')) AS Destino FROM
Pedidos;
Esta consulta devuelve los campos Fecha, Nombre del Producto y
Cantidad de la tabla pedidos, añadiendo un campo al final
con el valor Madrid si el código posta está dentro
del intervalo, en caso contario devuelve Nacional.
Un Pequeño Manual de
Estilo
Siempre es bueno intentar hacer las cosas de igual modo para que
el mantenimiento
y la revisión nos sea una labor lo más sencilla
posible. En lo que a mi respecta utilizo las siguiente normas a la hora
de elaborar sentecias SQL:
- Las cláusulas siempre las escribo con
Mayúsculas. - Los operadores lógicos de sentencias siempre
con Mayúsculas. - Las operaciones
siempre la primera letra con mayúsculas y el resto en
minúsculas. - Los operadores lógicos incluidos en otros
operadores la primera letra con mayúsculas y el resto
con minúculas.
Los Nombres de las Tablas, Campos y Consultas, los
escribo siempre la primera letra con mayúsculas y el resto
con minúsculas, en algunos casos utilizo el carácter
"_" para definir mejor el nombre: Detalles_Pedidos.
Aunque con el motor Jet se pueden utilizar acentos y espacios en
blanco para nombrar los campos, las tablas y las consultas no los
utilizo porque cuando se exportar tablas a otros sistemas los
acentos y los espacios en blanco pueden producir errores
innecesarios.
Recuerda siempre que si utilizas espacios en blanco para llamar
tablas o consultas cada vez que hagas referencias a ellos en una
consulta debes incluir sus nombres entre corchetes.
SELECT [ID de Pedido], [Nombre del Producto], Cantidad FROM
[Detalles del Pedido];
Autor:
Cesar Orozco Manotas
Analista y programador
Barranquilla, Colombia
Página anterior | Volver al principio del trabajo | Página siguiente |